package com.ihealthway.all.groupbuy.filters;

import com.ihealthway.all.groupbuy.vo.UserInfo;
import com.ihealthway.all.commons.Constants;
import com.ihealthway.all.view.ProxyRedirectView;
import io.github.elkan1788.mpsdk4j.vo.MPAccount;
import org.nutz.ioc.impl.PropertiesProxy;
import org.nutz.lang.Strings;
import org.nutz.log.Log;
import org.nutz.log.Logs;
import org.nutz.mvc.ActionContext;
import org.nutz.mvc.ActionFilter;
import org.nutz.mvc.Mvcs;
import org.nutz.mvc.View;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;

/**
 * A web login filter
 *
 * @author 凡梦星尘(elkan1788@gmail.com)
 */
public class SessionFilter implements ActionFilter {

    private static final Log logger = Logs.get();

    private String wechatOauthUrl = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s" +
            "&redirect_uri=%s&response_type=code&scope=snsapi_userinfo&state=%s#wechat_redirect";

    private PropertiesProxy conf = Mvcs.getIoc().get(PropertiesProxy.class, "conf");

    private List<String> ignorePath = new ArrayList<>();

    public void init() {
        if (ignorePath.isEmpty()) {
            ignorePath.addAll(conf.getList("session_filter_path", ","));
        }
    }

    @Override
    public View match(ActionContext ctx) {
        init();

        HttpServletRequest req = (HttpServletRequest) ctx.get("javax.servlet.http.HttpServletRequest");
        HttpSession session = req.getSession();

        // Filter session can't get
        if (session == null) {
            logger.error("There wasn't get session object!!!");
            return null;
        }

        // Filter other path under admin action without login
        String ui = req.getRequestURI();
        String scheme = req.getScheme();
        String ctxPath = req.getContextPath();
        if (!scheme.isEmpty()) {
            ui = ui.substring(ctxPath.length());
        }
        String suffixPath = ui.substring(ui.lastIndexOf("/") + 1, ui.lastIndexOf("."));
        logger.infof("ui:%s, scheme:%s, ctx:%s, suf:%s", ui, scheme, ctxPath, suffixPath);

        if (ui.startsWith("/admin")
                && !ignorePath.contains(suffixPath)) {

            if (session.getAttribute(Constants.ADMIN_LOGIN_SESSION) == null) {
                logger.infof("Admin URI without login action. => %s", ui);
                return new ProxyRedirectView("/admin/login.do");
            }
        } else if (ui.startsWith("/front")
                && !ignorePath.contains(suffixPath)) {

            String state = ui.replace("/", "0");
            state = state.replace(".", "1");
            state = state.replace("?", "2");
            state = state.replace("=", "3");
            if (Strings.isNotBlank(req.getQueryString())) {
                state += ("2" + req.getQueryString().replace("=", "3"));
            }
            logger.infof("State: %s", state);

            UserInfo userInfo = (UserInfo) session.getAttribute(Constants.WECHAT_LOGIN_SESSION);
            if (userInfo == null) {
                logger.infof("Front URI without login action. => %s", ui);
                String redirectUrl = String.format("%1$s://%2$s%3$s/wechat/oauth2CallBack.do", scheme,
                        conf.get("server_domain"), ctxPath);
                logger.infof("Wechat redirect URL: %s", redirectUrl);
                try {
                    redirectUrl = URLEncoder.encode(redirectUrl, "UTF-8");
                } catch (UnsupportedEncodingException e) {
                    logger.errorf("Encode wechat redirect URL failure!!! => %s", redirectUrl);
                    logger.error(e);
                }

                MPAccount mp = ctx.getIoc().get(MPAccount.class, "mpAct");
                String url = String.format(wechatOauthUrl, mp.getAppId(), redirectUrl, state);

                return new ProxyRedirectView(url);
            } else if ((userInfo.getCompanyId() == null || userInfo.getCompanyId().intValue() <= 0)
                    && !ignorePath.contains(suffixPath)) {
                logger.infof("Front URI and user without complete info. => %s, %s", ui, userInfo.getOpenId());
                return new ProxyRedirectView("/front/personal/register.do?re=" + state);
            } /*else if (userInfo.getCompanyId() != null
                    && userInfo.getCompanyId().intValue() > 0
                    && !ignorePath.contains(suffixPath)) {
                logger.infof("Front URI and user already complete info. => %s, %s", ui, userInfo.getOpenId());
                return new ProxyRedirectView("/front/shop/home.do");
            }*/
        }

        return null;
    }
}
